Amazon Forecastにwhat-if分析機能が追加:関連する時系列データが変化した際の動きを分析可能になりました
こんちには。
データアナリティクス事業本部機械学習チームの中村です。
今回はAmazon Forecastの新機能であるwhat-if分析についてご紹介します。
AWS公式ブログでは以下の記事で紹介されています。
Amazon Forecastの概要
まずAmazon Forecastの概要をおさらいします。
Amazon Forecastは時系列データを予測するサービスです。
入力できる情報には以下の3種類があります。
- TARGET_TIME_SERIES(TTS)
- 予測対象(ターゲット)となる時系列データ。(例: 需要予測の場合は需要のデータ)
- 時系列で変化しない情報(例: 店舗ID)を含めることで分析軸を追加可能。
- RELATED_TIME_SERIES(RTS)
- 関連する時系列データ。(例: 需要予測の場合は価格など)
- TTSに付加した分析軸はこちらにも追加が必要。
- ITEM_METADATA
- アイテムのメタデータを追加することが可能。(例: 商品のブランドなど)
TTSは全てのケースでおいて必須のデータですが、what-if分析ではRTSも必要となります。
what-if分析とは
what-if分析はRTSが変化した際に、TTSがどのように変化するかを分析するための機能です。
例えば「需要予測」の場合は、「需要(TTS)」とは別の関連する時系列データである「価格(RTS)」を過去に遡って下げたと仮定した場合に、 予測した「需要(TTS)」がどの程度変化するのかを分析することが可能になります。
また、Amazon Forecastにかかる費用は以下の通りです。
- データのインポート
- Predictorのトレーニング
- 予測したデータポイント数
- 予測の説明
このうち、What-if分析はデータポイントを予測するため、「予測したデータポイント数」の部分にコストが掛かってくるのでご注意ください。
(実際本記事の通りに実行すると、60ドル程度は必要になりますので留意頂ければと思います)
what-if分析のトライ
今回関連するリソースは以下のような階層構造になっています。
What-if分析に相当するのは、オレンジ部分で、一旦Forecastまで作成した上で構築する必要があります。
S3の準備
事前にバケット作成しておきます。(今回は以下)
- バケット名: sample-nakamura-2022-09-09-forecast
以下のGitHubに、公開されているデータセットがあります。
ここから以下の2つのファイルをダウンロードします。
- consumer_electronics_TTS.csv
- consumer_electronics_RTS.csv
これらをS3のそれぞれアップロードしておきます。(今回は以下)
- s3://sample-nakamura-2022-09-09-forecast/target/consumer_electronics_TTS.csv
- s3://sample-nakamura-2022-09-09-forecast/related/consumer_electronics_RTS.csv
Dataset group作成
「View dataset groups」を押下し、データセットグループ一覧を表示します。
「Create dataset group」を押下します。
Dataset groupの情報を以下のように入力し、末尾の「Next」を押下します。
- Dataset group name: sample_nakamura_what_if_dsg
- Forecasting domain: Custom
Dataset(ターゲット側)作成
Datasetの情報を以下のように入力します。
- Dataset name: sample_nakamura_what_if_tts
- Frequency of your data: 1 months
- Data schema: JSON builderをチェック
またJSON schemaには以下を設定し、Timestamp formatにはyyyy-MM-dd
を設定します。
{ "Attributes": [ { "AttributeName": "item_id", "AttributeType": "string" }, { "AttributeName": "store_id", "AttributeType": "string" }, { "AttributeName": "timestamp", "AttributeType": "timestamp" }, { "AttributeName": "target_value", "AttributeType": "float" } ] }
Dataset importの設定は以下とします。
- Dataset import name: sample_nakamura_what_if_tts_import
- Select time zone: Do not use time zone
- Import file type: CSV
- Data location: s3://sample-nakamura-2022-09-09-forecast/target/consumer_electronics_TTS.csv
IAM roleは、Create a New Roleを選択すると以下のダイアログがでるので、
Specific S3 bucketsを以下のように設定して、「Create role」を押下します。
- sample-nakamura-2022-09-09-forecast
ちなみに作成されるロールにアタッチされるポリシーは以下のようになります。
(書き込み権限もあるので、後述のエクスポート時もこちらを使用していきます。)
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:ListBucket" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::sample-nakamura-2022-09-09-forecast" ] }, { "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::sample-nakamura-2022-09-09-forecast/*" ] } ] }
ロールが作成されるので、その後「Start」を押下します。
その後Importが開始されます。
Dataset group一覧から作成したDataset groupを選択すると、
直後は「Create pending」となっているため、以下のようにActiveとなるまで待ちます。
Dataset(関連データ側)作成
what-if分析には、Related time series dataが必要となるため、上記の画面で「Import」を押下します。
Datasetの情報を以下で入力します。
- Dataset name: sample_nakamura_what_if_rts
- Frequency of your data: 1 months
- Data schema: JSON builderをチェック
またJSON schemaには以下を設定し、Timestamp formatにはyyyy-MM-dd
を設定します。
{ "Attributes":[ { "AttributeName":"item_id", "AttributeType":"string" }, { "AttributeName":"store_id", "AttributeType":"string" }, { "AttributeName":"timestamp", "AttributeType":"timestamp" }, { "AttributeName":"price", "AttributeType":"float" }, ] }
Dataset importの設定は以下とします。
- Dataset import name: sample_nakamura_what_if_rts_import
- Select time zone: Do not use time zone
- Import file type: CSV
- Data location: s3://sample-nakamura-2022-09-09-forecast/target/consumer_electronics_RTS.csv
IAM roleは、先ほどと同じロールを指定します。(データ格納先のバケットは同じの場合)
その後「Start」を押下します。
Importが始まるので、先ほどと同様にRelated time series dataが「Active」となるまで待ちます。
Predictor作成
次にPredictorを作成します。先ほどの画面で、Predictor trainingの横にある「Start」を押下します。
Predictor settingsは以下の値で設定します。
- Predictor name: sample_nakamura_what_if_predictor
- Forecast frequency: 1 month(s)
- Forecast horizon: 3
- Forecast dimensions: store_id
- Forecast quantiles:
- Forecast quantile: Forecast quantile 1, Value: 0.10
- Forecast quantile: Forecast quantile 2, Value: 0.50
- Forecast quantile: Forecast quantile 3, Value: 0.90
他はデフォルトのまま、ページ下部の「Create」を押下します。
すると、Trainingが開始され、Predictor一覧で残り時間が表示されます。
(今回は2時間程度必要でした)
Forecast作成(予測の実行)
Predictor一覧から作成したPredictorを選択すると、「Create forecast」ボタンがありますので、
そこで予測を実行します。
Forecast detailsは以下の値で設定します。
- Forecast name: sample_nakamura_what_if_forecast
- Predictor: sample_nakamura_what_if_predictor
- Item for generating forecasts: All Items
作成が開始されるので、結果を待ちます。
(残り時間が表示され、今回は40分程度かかりました)
作成が終わったら、forecastを選択し、以下の「Create forecast export」を押下します。
Export detailsで以下を入力します。
- Export name: sample_nakamura_what_if_forecast_export
- IAM role: インポート時に作成したものと同じロールを指定
- Export file type: CSV
- S3 forecast export location: s3://sample-nakamura-2022-09-09-forecast/export
ページ下部の「Create Export」を押下して完了を待ちます。
what-if分析の作成
ダッシュボード画面からwhat-if分析が作成できます。「Explore what-if analysis」を押下します。
「Create」を押下します。
What-if analysis detailsを以下のように設定します。
- What-if analysis name: sample_nakamura_what_if_analysis
- Select forecast: sample_nakamura_what_if_forecast
- Item selection: Select all items
ページ下部の「Create what-if analysis」を押下します。
しばらく経過すると、What-if analysisのStatusがActiveとなります。
what-if分析のForecast作成(予測の実行)
上記の画面から、What-if forecastの「Create」を押下して進みます。
What-if forecast detailsに以下を入力します。
- What-if forecast name: sample_nakamura_what_if_analysis_forecast
- What-if forecast definition method: Use transformation functions
- Transformation function builder:
- Action
- Operation: MULTIPLY, AttributeName: price, Value: 0.90
- Conditions:
- AttributeName: timestamp, AttributeValue: 2019-09-01, Condition: GREATER_THAN
上記の設定内容は、2019-09-01以降のpriceデータに0.9を乗算した場合に、
Targetがどのように変化するかを、What-if分析するような記述となっています。
なお、数式で表現できないような値を設定したい場合は、
definition methodに「Define the what-if forecast with a replacement dataset」を選択し、
データを置き換えたRelated Time SeriesデータをS3からImportすることで、What-if分析をすることが可能です。
入力をしたらページ下部の「Create」を押下します。
すると以下のように作成中となるので、しばらく待ちます。
StatusがActiveとなったら、ページ下部に移動し、以下のWhat-if forecast exportで
「Create export」を押下します。
インポート時に作成したものと同じロールを指定
Export detailsで以下を入力します。
- Export name: sample_nakamura_what_if_analysis_forecast_export
- What-if forecasts: sample_nakamura_what_if_analysis_forecast
- S3 forecast export location: s3://sample-nakamura-2022-09-09-forecast/export_what_if
- IAM role: インポート時に作成したものと同じロールを指定
ページ下部の「Create Export」を押下して完了を待ちます。
結果の比較
エクスポート結果をダウンロードして比較していきます。
aws s3 cp s3://sample-nakamura-2022-09-09-forecast/export ./export --recursive aws s3 cp s3://sample-nakamura-2022-09-09-forecast/export_what_if ./export --recursive
可視化のため、Pythonのコードを準備しました。
import pathlib import pandas as pd from matplotlib import pyplot as plt import seaborn as sns sns.set(style='darkgrid') from datetime import datetime # 学習データ読み込み tts_df = pd.read_csv("./consumer_electronics_TTS.csv") # 推論結果読み込み def read_csv_files(src_path: str): df = pd.DataFrame([]) for p in pathlib.Path(src_path).glob("*.csv"): # print(p) _df = pd.read_csv(p) if len(df)==0: df = _df else: df = pd.concat([df, _df], axis=0) df = df.sort_values(['item_id', 'store_id', 'date']).reset_index(drop=True) df['yyyy-mm-dd'] = [i[:10] for i in df['date']] return df base_df = read_csv_files("./export") whatif_df = read_csv_files("./export_what_if") # 描画 query_str = 'item_id == "item_001" and store_id == "store_001"' fig, axes = plt.subplots(2, 1, figsize=(10, 6), dpi=100, sharex="col") fig.suptitle(query_str) ax = axes[0] sns.lineplot(data=tts_df.query(query_str), x='timestamp', y='demand', marker="o", ax=ax, label="train(target)", color=colors[0]) sns.lineplot(data=base_df.query(query_str), x='yyyy-mm-dd', y='p50', marker="o", ax=ax, label="forecast(p50)", color=colors[1]) sns.lineplot(data=whatif_df.query(query_str), x='yyyy-mm-dd', y='sample_nakamura_what_if_analysis_forecast_p50', marker="o", ax=ax, label="what-if-forecast(p50)", color=colors[2]) ax.set_ylim([100, 500]) ax = axes[1] sns.lineplot(data=rts_df.query(query_str), x='timestamp', y='price', marker="o", ax=ax, label="train(related)", color=colors[0]) sns.lineplot(data=rts_df.query(query_str).query('timestamp > "2019-09-01"'), x='timestamp', y='price_whatif', marker="o", ax=ax, label="what-if", color=colors[2]) [i.set_rotation(90) for i in ax.get_xticklabels()] ax.set_ylim([40, 150]) plt.tight_layout() plt.tight_layout()
結果は以下のようになります。(item_id: "item_001", store_id: "store_001"の場合)
上のdemandが予測対象となる時系列データで、下のpriceがRelatedな時系列データとなる情報です。
demand, priceそれぞれ青線で描かれている箇所がPredictorの学習に使用されています。
オレンジ線は、通常のPredictorのForecast結果(p50)で、これがベースラインとなります。
グリーン線がwhat-if分析に関するデータで、priceが0.9掛けだったら、
demandにどのような影響がでるかを確認できます。
影響としては、priceが低下すると、demandが上昇するといったような予測をしているようです。
これは、学習に使用したdemandとpriceが逆相関を持っていることをうまく反映しています。
この結果は、item_id、store_idごとにそれぞれ影響度を確認することが可能です。
興味のある方は他のケースも確認してみてください。
まとめ
いかがでしたでしょうか?
what-if分析で、過去を振り返って様々な仮説を検証することができるので、分析の幅が広がりそうですね。
Amazon Forecastをご利用の方は是非お試しください。
こちらの記事がAmazon Forecastを活用する際の参考になれば幸いです。